/* ===================================
Michal Kowalczyk
2010 EZI
==================================== */

#pragma once
#include "entities.h"
// views.h - the graphical representation of entites + camera

/*
glTexCoord2f(1.0f, 0.0f) Right Top 
glTexCoord2f(0.0f, 0.0f) Left Top 
glTexCoord2f(0.0f, 1.0f) Left Bottom
glTexCoord2f(1.0f, 1.0f) Right Bottom 
*/


class BaseView: public IView
{
protected:
	Position3D m_position;
	EntityID m_id;
	STLogger & logger;
	EntityManager & entityManager;
public:
	BaseView(Position3D position, EntityID id): m_position(position),  m_id(id), logger(STLogger::Instance()), \
		entityManager(EntityManager::Instance()) {};
	virtual ~BaseView() {};
	virtual std::string getType() = 0;
	virtual bool setup() = 0;
	virtual void update()
	{
		EntityPtr tmpEntity(entityManager.getEntity(m_id));
		m_position = tmpEntity->getPosition3D();
	};
	virtual void render() = 0;
};


class ViewListener
{
private:
	EntityManager & entityManager;
	Renderer & renderer;
	STLogger & logger;
	std::string mediaPath;
	float xdist, zdist, distance;
	int size;
	const float deltaCollision;
public:
	ViewListener(): entityManager(EntityManager::Instance()), logger(STLogger::Instance()), \
		renderer(Renderer::Instance()), deltaCollision(2.5f) {};
	// here add new slots for signals/events
	void handleNewActorSignal(int id);
	CollisionInfo handleActorMovedSignal(int id);
};


class InversionLayerView: public BaseView
{
private:
	std::string m_type;
	float width;
	InversionLayer * invlay;
public:
	InversionLayerView(Position3D position, int id): m_type("inversionlayer"), BaseView(position, id) {};
	~InversionLayerView() {};
	bool setup() ;
	void update();
	std::string getType()
	{
		return m_type;
	}
	void render();
};


class ElectronView: public BaseView
{
private:
	std::string m_type;
public:
	ElectronView(Position3D position, int id): m_type("electron"), BaseView(position, id) {};
	~ElectronView() {};
	bool setup () { return true; };
	void update () { BaseView::update(); };
	std::string getType()
	{
		return m_type;
	}
	void render();
};


class HoleView: public BaseView
{
private:
	std::string m_type;
public:
	HoleView(Position3D position, int id): m_type("hole"), BaseView(position, id) {};
	~HoleView() {};
	bool setup () { return true; };
	void update () { BaseView::update(); };
	std::string getType()
	{
		return m_type;
	}
	void render();
};
